package com.czmh.etc.onlinepubsys.services.mingchuang.impl;

import com.alibaba.fastjson.JSON;
import com.czmh.etc.onlinepubsys.configuration.WxAppletConfig;
import com.czmh.etc.onlinepubsys.json.mingchuang.JSONResult;
import com.czmh.etc.onlinepubsys.response.mingchuang.WechatOrderResponse;
import com.czmh.etc.onlinepubsys.services.mingchuang.IWechatService;
import com.czmh.etc.onlinepubsys.utils.WeiXinPayUtils;
import com.czmh.etc.onlinepubsys.utils.mingchuang.HttpUtil;
import com.czmh.etc.onlinepubsys.utils.mingchuang.PayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.SortedMap;
import java.util.TreeMap;

@Slf4j
@Service
public class WechatSerivceImpl implements IWechatService {
    @Autowired
    private WxAppletConfig payConfig;

    @Override
    public boolean checkSign(SortedMap<String, String> map) {
        String sign = PayUtil.createSign(map, payConfig.getKey());
        return sign.equals(map.get("sign"));
    }

    @Override
    public JSONResult unifiedDepositOrder(String openId, String orderNo, String body, Integer amount) {
        JSONResult result = new JSONResult();
        SortedMap<String,String> paramMap = new TreeMap<>();
        paramMap.put("appid", payConfig.getAppId());
        paramMap.put("mch_id", payConfig.getMchId());
        paramMap.put("nonce_str", PayUtil.getNonceStr());
        paramMap.put("body", body);
        paramMap.put("out_trade_no", orderNo);
        paramMap.put("total_fee", amount.toString());
        paramMap.put("spbill_create_ip", PayUtil.getLocalIp());
        paramMap.put("notify_url", payConfig.getDepositNotifyUrl());
        paramMap.put("trade_type", payConfig.getTradeType());
        paramMap.put("openid", openId);
        String sign = PayUtil.createSign(paramMap, payConfig.getKey());
        paramMap.put("sign", sign);

        String xml = PayUtil.mapToXml(paramMap);
        String respStr = HttpUtil.postWX(payConfig.getUnifiedOrderUrl(), xml);

        SortedMap<String, String> map = WeiXinPayUtils.parseXml(respStr);
        if (!checkSign(map)) {
            log.info("验证微信返回签名失败");
            result.setCode(JSONResult.FAIL);
            result.setMessage("验证微信返回签名失败");
            return result;
        }

        WechatOrderResponse wechatResp = PayUtil.toObject(respStr, WechatOrderResponse.class);

        if (wechatResp.getReturn_code().equals("SUCCESS") && wechatResp.getResult_code().equals("SUCCESS")) {
            //调起数据签名 appId,nonceStr,package,signType,sign,timeStamp
            String prepay_id = wechatResp.getPrepay_id();
            SortedMap<String, String> retMap = new TreeMap<>();
            retMap.put("appId", wechatResp.getAppid());
            retMap.put("nonceStr", wechatResp.getNonce_str());
            retMap.put("package", "prepay_id="+prepay_id);
            retMap.put("signType", "MD5");
            retMap.put("timeStamp", PayUtil.getCurrentTimeStamp());
            retMap.put("sign", PayUtil.createSign(retMap, payConfig.getKey()));

            result.setCode(JSONResult.SUCCESS);
            result.setRspData(JSON.toJSONString(retMap));
        } else {
            result.setCode(JSONResult.FAIL);
            result.setMessage(wechatResp.getErr_code_des());
        }
        return result;
    }

    @Override
    public JSONResult unifiedOrder(String openId, String orderNo, String body, Integer amount) {
        JSONResult result = new JSONResult();
        SortedMap<String,String> paramMap = new TreeMap<>();
        paramMap.put("appid", payConfig.getAppId());
        paramMap.put("mch_id", payConfig.getMchId());
        paramMap.put("nonce_str", PayUtil.getNonceStr());
        paramMap.put("body", body);
        paramMap.put("out_trade_no", orderNo);
        paramMap.put("total_fee", amount.toString());
        paramMap.put("spbill_create_ip", PayUtil.getLocalIp());
        paramMap.put("notify_url", payConfig.getNotifyUrl());
        paramMap.put("trade_type", payConfig.getTradeType());
        paramMap.put("openid", openId);
        String sign = PayUtil.createSign(paramMap, payConfig.getKey());
        paramMap.put("sign", sign);

        String xml = PayUtil.mapToXml(paramMap);
        String respStr = HttpUtil.postWX(payConfig.getUnifiedOrderUrl(), xml);

        SortedMap<String, String> map = WeiXinPayUtils.parseXml(respStr);
        if (!checkSign(map)) {
            log.info("验证微信返回签名失败");
            result.setCode(JSONResult.FAIL);
            result.setMessage("验证微信返回签名失败");
            return result;
        }

        WechatOrderResponse wechatResp = PayUtil.toObject(respStr, WechatOrderResponse.class);

        if (wechatResp.getReturn_code().equals("SUCCESS") && wechatResp.getResult_code().equals("SUCCESS")) {
            //调起数据签名 appId,nonceStr,package,signType,sign,timeStamp
            String prepay_id = wechatResp.getPrepay_id();
            SortedMap<String, String> retMap = new TreeMap<>();
            retMap.put("appId", wechatResp.getAppid());
            retMap.put("nonceStr", wechatResp.getNonce_str());
            retMap.put("package", "prepay_id="+prepay_id);
            retMap.put("signType", "MD5");
            retMap.put("timeStamp", PayUtil.getCurrentTimeStamp());
            retMap.put("sign", PayUtil.createSign(retMap, payConfig.getKey()));

            result.setCode(JSONResult.SUCCESS);
            result.setRspData(JSON.toJSONString(retMap));
        } else {
            result.setCode(JSONResult.FAIL);
            result.setMessage(wechatResp.getErr_code_des());
        }
        return result;
    }

    @Override
    public JSONResult getPayState(String orderNo) {
        JSONResult result = new JSONResult();
        SortedMap<String,String> params = new TreeMap<>();
        params.put("appid", payConfig.getAppId());
        params.put("mch_id", payConfig.getMchId());
        params.put("nonce_str", PayUtil.getNonceStr());
        params.put("out_trade_no", orderNo);
        params.put("sign", PayUtil.createSign(params, payConfig.getKey()));

        String xml = PayUtil.mapToXml(params);
        String respStr = HttpUtil.postWX(payConfig.getOrderQueryUrl(), xml);
        SortedMap<String, String> map = WeiXinPayUtils.parseXml(respStr);

        if (!checkSign(map)) {
            log.info("验证微信返回签名失败");
            result.setCode(JSONResult.FAIL);
            result.setMessage("验证微信返回签名失败");
            return result;
        }

        if ("SUCCESS".equals(map.get("return_code")) && "SUCCESS".equals(map.get("result_code"))) {
            if ("SUCCESS".equals(map.get("trade_state"))) {
                result.setMessage("支付成功");
            } else {
                result.setCode(JSONResult.FAIL);
                result.setMessage("支付失败");
            }
        } else {
            result.setCode(JSONResult.FAIL);
            result.setMessage("服务器忙请稍后再试");
        }

        return result;
    }
}
